
import csv
import sys
import getopt
from tagger import COL
from elementtree.SimpleXMLWriter import XMLWriter
from datetime import datetime
import re
class config:
    skipHeader = True
    thres = 5 # 
    fmt = "%Y-%m-%dT%H:%M:%S.000"
def usage():
    print('''
usage packtln [-h] -o format <input_csv>
    ''')
    sys.exit(2)

def parse_args():
    try:
        opts, args = getopt.getopt(sys.argv[1:], "o:hs", ["help", "output="])
    except getopt.GetoptError as err:
        # print help information and exit:
        print (str(err)) # will print something like "option -a not recognized"
        usage()
        sys.exit(2)
    output = None
    verbose = False
    if (len(args) == 0):
        usage()
    else :
        config.input = args[0]
    for o, a in opts:
        if o == '-s':
            config.skipHeader = True
        elif o in ("-h", "--help"):
            usage()
        elif o in ("-o", "--output"):
            config.output = a
        else:
            assert False, "unhandled option"

class Line:
    timere = re.compile(r'(\d+)/(\d+)/(\d+)_(\d+):(\d+):(\d+)(\.(\d+))?')
    def __init__(self, row):
        self.time = Line.toTime(row[COL.time])
        self.tag = row[COL.tag] 
        self.row = row
    def __str__(self):
        return str(self.row)
    @staticmethod    
    def toTime(str):
        r = Line.timere.match(str).groups()
        r = list(r)
        del r[6]
        tmp = []
        
        for x in r:
            if (x == None):
                tmp.append(0)
            else :
                tmp.append(int(x))
        r = tmp
        return datetime(r[0], r[1], r[2], r[3], r[4], r[5], r[6])

def error_quit(msg):
    print (msg)
    sys.exit(-1)

_lastTime = None
_store = dict()
def addRowInfo(row):
    global _lastTime
    global _store
    line = Line(row)
    if ((_lastTime != None)  and _lastTime < line.time):
        error_quit("time column is not in decreasing order")
    _lastTime = line.time;
    if (line.tag == ''):
        plainOutput(line)
    elif (line.tag in _store):
            value = _store.get(line.tag)
            minTime = min(value[0], line.time)
            rowlst = value[1];
            rowlst.append(line)
            value = (minTime,) + value[1:];
            _store[line.tag] = value
    else :
        _store[line.tag] = (line.time, [line]);
            
xml = XMLWriter(sys.stdout)
def plainOutput(line):
    global xml
    fmt = config.fmt
    row = line.row
    xml.start("event", start=line.time.strftime(fmt),
            title=row[COL.src] + "@" + row[COL.host] + "," + row[COL.action] + 
            ":" + row[COL.target])
    xml.data(row[COL.src] + "@" + row[COL.host] + '[' + row[COL.src] + 
             ']\n' + 'tamper:' + row[COL.tamper] + "\n" + 'misc:' + row[COL.misc])
    xml.end('event')
    
def incrementalOutput():
    global xml
    global _store
    global _lastTime
    toremove = []
    for k, v in _store.items():
        starttime = v[0]
        lines = v[1]
        fmt = config.fmt
        if (starttime - _lastTime).seconds > config.thres:
            endtime = lines[0].time
            xml.start("event", start=starttime.strftime(fmt),
                      end=endtime.strftime(fmt),
                      title=k,
                      durationEvent='true')
            
            #l = lines[0]
            targets = [l.row[COL.target] for l in lines]
            s = ''
            for t in targets:
                s = s + t + "<br/>"
            xml.data(s)
            xml.end('event')
            toremove.append(k)
    for k in toremove:
        del _store[k]
    
            
        
import codecs
def process():
    csvReader = csv.reader(codecs.open(config.input, 'r', 'ascii',
                                       errors='ignore'))
                                       
    #csvReader = csv.reader(open(config.input,'r'))
    # csvReader = csv.reader(open(config.input,'r',))
    '''csvWriter = csv.writer(sys.stdout)
    csvWriter.writerow(['time', 'src' ,'host','usr' ,
                        'action' ,'target' ,'misc' ,
                        'tamper' ,'tag'])'''
    global xml
    xml.start("data", dict({'date-time-format':'iso8610'}))
    for row in csvReader:
        if config.skipHeader == True:
            config.skipHeader = False
            continue
        addRowInfo(row)
        incrementalOutput()
    xml.end('data')
      
if (__name__ == '__main__'):
    parse_args()
    process()
